#include "analysis.h"

analysis::analysis()
{

}

quint16 analysis::crc16ForModbus(const QByteArray &data,int flag)
{
    static const quint16 crc16Table[] =
    {
        0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
        0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
        0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
        0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
        0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
        0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
        0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
        0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
        0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
        0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
        0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
        0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
        0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
        0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
        0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
        0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
        0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
        0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
        0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
        0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
        0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
        0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
        0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
        0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
        0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
        0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
        0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
        0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
        0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
        0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
        0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
        0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
    };

    quint8 buf;
    quint16 crc16 = 0xFFFF;

    for ( auto i = 0; i < data.size()-2; ++i )
    {
        buf = data.at( i ) ^ crc16;
        crc16 >>= 8;
        crc16 ^= crc16Table[ buf ];
    }

   auto crcl = crc16&0xFF; //crc低位
   auto crch = crc16>>8;//crc高位
   auto crc161=0xFFFF;
   crc161 = (((crc161&0x0)|crcl)<<8)|(crch);
   if(flag)
   {
    return crc16;
   }
   else
   {
    return crc161;
   }
}

//连接两个quint8数据为一个quint16数据
quint16 BondTwoUint8ToUint16(quint8 preNum, quint8 afterNum)
{
    quint16 bondNum = (preNum << 8) | afterNum;
    return bondNum;
}

//字节反转函数
void byteReverse(QString &coils)
{
    // 定义临时字符变量
    QChar temp;

    for(int i=0; i < 4; i++)
    {
        temp = coils[i];        // 将第i个元素存入临时字符变量
        coils[i] = coils[8-i-1];  // 将第i个字符元素和第n-i-1个元素对调
        coils[8-i-1] = temp;    // 将临时字符变量的值赋给第n-i-1个元素
    }
}


void ByteToHexString(QString &str, QByteArray &ba)
{
    QString strs = ba.toHex().toUpper();//直接转换中间没有空格
    for(int i=0;i<strs.length();i+=2)
    {
        QString str_1 = strs.mid (i,2);
        str += str_1;
        str += " ";
    }
}

//从机报文解析
void analysis::ParseResponseMessage(QByteArray msg, quint8 addr)
{
        readseting = new QSettings("Data.ini", QSettings::IniFormat);
        if(msg.isEmpty()==false)
        {
            mb_addr=addr;
            recvModbusmsg = msg;
            MB_satae state =parse_Modbus_Msg(recvModbusmsg);
            qDebug()<< state;
            parse_Modbus_MB_satae(state);
        }
}

//读取状态
MB_satae analysis::parse_Modbus_Msg(QByteArray ba)
{
    qDebug() << ba.toHex().toUpper()  << ba.length() <<endl;
    //判断帧长度
    if(ba.length()<8)
    {
        len = 8-ba.length();
        errorMsg = "无响应，报文长度过短，数据少"+QString::number(len)+"位"+"\n";
        qDebug()<< "Lenghtrerror";
        return MB_SLAVE_STATE_PACKET_OTHER;
    }
    if(ba.length()>256)
    {
        errorMsg = "无响应，报文长度过长\n";
        return MB_SLAVE_STATE_PACKET_OTHER;
    }
    //计算帧数据字节是否和数据长度正确
    //线圈字节数
    quint8 csize = (quint8)ba.at(6);
    //寄存器字节数
    quint8 rsize = (quint8)ba.at(6);
    //去除校验码
    QByteArray bass = ba.mid(0,ba.size()-2);
    //数据段长度
    QByteArray dsize = bass.mid(7,bass.size());
    //写入数据数量
    wnum = BondTwoUint8ToUint16((quint8)ba.at(4),(quint8)ba.at(5));
    //判断从机地址
    if(ba[0]!= mb_addr)
    {
        errorMsg = "从机地址错误";
        return MB_SLAVE_STATE_PACKET_OTHER;
    }

    auto crc16ForModbus = analysis::crc16ForModbus(ba,CRC_FLAG);
    qDebug() << "crc16ForModbus:"   << crc16ForModbus   << QString::number( crc16ForModbus, 16 ).toUpper();
    auto bus=  ba.mid(ba.length()-2,ba.length());
    auto crcl = crc16ForModbus&0xFF; //crc低位
    auto crch = crc16ForModbus>>8;//crc高位
    quint8 crchs = bus.at(0);//crc高位
    quint8 crcls = bus.at(1);//crc低位
    //判断CRC
    if(crcls!=crcl||crch!=crchs)
    {
        errorMsg = "CRC错误";
        qDebug()<< "校验码错误CRCrerror";
        return MB_SLAVE_STATE_PACKET_OTHER;
    }
    //判断功能码
    switch(ba[1])
    {
    case 0x01: mb_code =0x01;
        //起始地址
        mb_startaddr = ((quint8)ba[2])*256+(quint8)ba[3];
        //数据量
        mb_num = ((quint8)ba[4])*256+(quint8)ba[5];

        if(mb_num>2000)
        {
            errorMsg = "03异常,写入线圈数量超过2000个\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else if(mb_num==0)
        {
            errorMsg = "03异常,写入线圈数量为0个\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else
            if((mb_startaddr+mb_num-1)>65535)
            {
                errorMsg = "02异常，线圈读取非法,请求报文中起始地址后可读取的线圈数量小于读取数量\n";
                return MB_SLAVE_STATE_DATAADDR_ERROR;
            }
            else if(ba.length()>8)
            {
                len=ba.length()-8;
                errorMsg = "无响应，长度过长，数据多"+QString::number(len)+"位";
                qDebug()<< "this is Lenghtrerror";
                return MB_SLAVE_STATE_PACKET_OTHER;
            }
            else
            {
                return MB_SLAVE_STATE_PACKET_PROCESS;
            }
        break;
    case 0x03:mb_code=0x03;
        qDebug()<< "this is 03 function";
        //起始地址
        mb_startaddr = ((quint8)ba[2])*256+(quint8)ba[3];
        //数据量
        mb_num = ((quint8)ba[4])*256+(quint8)ba[5];
        if(mb_num>125)
        {
            errorMsg = "03异常,写入寄存器数量超过125个\n ";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else if(mb_num==0)
        {
            errorMsg = "03异常，读0个寄存器错误\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else
            if((mb_startaddr+mb_num-1)>65535)
            {
                errorMsg = "02异常，寄存器读取非法,请求报文中起始地址后可读取的寄存器数量小于读取数量\n ";
                return MB_SLAVE_STATE_DATAADDR_ERROR;
            }
            else if(ba.length()>8)
            {
                len=ba.length()-8;
                errorMsg = "无响应，长度过长，数据多"+QString::number(len)+"位+\n";
                qDebug()<< "this is Lenghtrerror";
                return MB_SLAVE_STATE_PACKET_OTHER;
            }
            else
            {
                return MB_SLAVE_STATE_PACKET_PROCESS;
            }
        break;
    case 0x0f:mb_code =0x0f;
        //起始地址
        mb_startaddr = ((quint8)ba[2])*256+(quint8)ba[3];
        //数据量
        mb_num = ((quint8)ba[4])*256+(quint8)ba[5];
        qDebug()<< "this is 0f function" << mb_code << mb_num;
        if(mb_num>1968)
        {
            errorMsg = "03异常,写入线圈数量超过1968个\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else if(mb_num==0)
        {
            errorMsg = "03异常，写入0个线圈错误\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else
            if((mb_startaddr+mb_num-1)>65535)
            {
                errorMsg = "02异常，线圈写入非法,请求报文中起始地址后可写入的线圈数量小于写入数量\n";
                return MB_SLAVE_STATE_DATAADDR_ERROR;
            }
            else if(csize!=dsize.size()||((wnum+7)/8)!=csize)
            {
                errorMsg = "写入字节字段不合法\n";
                return MB_SLAVE_STATE_PACKET_OTHER;
            }
            else
            {
                return MB_SLAVE_STATE_PACKET_PROCESS;
            }
        break;
    case 0x10:mb_code =0x10;qDebug()<< "this is 10 function";
        //起始地址
        mb_startaddr = ((quint8)ba[2])*256+(quint8)ba[3];
        //数据量
        mb_num = ((quint8)ba[4])*256+(quint8)ba[5];
        qDebug() << mb_num;
        if(mb_num>123)
        {
            errorMsg = "03异常,写入寄存器数量超过123个\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else if(mb_num==0)
        {
            errorMsg = "03异常，写入0个寄存器错误\n";
            return MB_SLAVE_STATE_DATA_ERROR;
        }
        else
            if((mb_startaddr+mb_num-1)>65535)
            {
                errorMsg = "02异常，寄存器入非法,请求报文中起始地址后可写入的寄存器数量小于写入数量\n";
                return MB_SLAVE_STATE_DATAADDR_ERROR;
            }
            else if(rsize!=dsize.size()||(wnum*2!=rsize))
            {
                errorMsg = "写入字节字段不合法\n";
                qDebug()<< "this is Lenghtrerror";
                return MB_SLAVE_STATE_PACKET_OTHER;
            }
            else
            {
                return MB_SLAVE_STATE_PACKET_PROCESS;
            }
        break;
    default:
        errorMsg = "01异常，功能码不支持 ";
        mb_code = ba[1];
        return MB_SLAVE_STATE_FUNCTION_ERROR;
        break;
    }
}


//状态处理
void analysis::parse_Modbus_MB_satae(MB_satae satae)
{
    switch(satae)
    {
    case MB_SLAVE_STATE_PACKET_PROCESS:
        switch(mb_code)
        {
        case 1:analysis01();
            break;
        case 3:analysis03();
            break;
        case 15:analysis0f();
            break;
        case 16:analysis10();
            break;
        }
        break;
        //异常处理
    case MB_SLAVE_STATE_DATAADDR_ERROR:
        abnormal_02();
        emit toUishowMsg(errorMsg);
        break;
    case MB_SLAVE_STATE_DATA_ERROR:
        abnormal_03();
        emit toUishowMsg(errorMsg);
        break;
    case MB_SLAVE_STATE_FUNCTION_ERROR:
        abnormal_01();
        emit toUishowMsg(errorMsg);
        break;
    case MB_SLAVE_STATE_PACKET_OTHER:
        emit toUishowMsg(errorMsg);
        break;
    }
}

//01功能码解析
void analysis::analysis01()
{
    QByteArray ba;
    quint16 num =((quint8)recvModbusmsg[4])*256+(quint8)recvModbusmsg[5];
    quint16 startaddr =((quint8)recvModbusmsg[2])*256+(quint8)recvModbusmsg[3];
    GetData0X01(ba,startaddr,num);
    //单元标识符
    sendModbusmsg[0]=recvModbusmsg[0];
    //功能码
    sendModbusmsg[1]=recvModbusmsg[1];
    //字节计数
    sendModbusmsg[2]=(quint8)ba.size();
    //状态值
    for(int i=3,j=0;j<ba.size();j++)
    {
        sendModbusmsg[i++]=(quint8)ba.at(j);
    }
    //显示读出的数据
    ReadCoilPackMsgToShow(startaddr,num,ba);
    //CRC校验
    QByteArray crcba(sendModbusmsg,5+(quint8)ba.size());
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    sendModbusmsg[3+(quint8)ba.size()] = crc16>>8;
    //CRC校验低位
    sendModbusmsg[4+(quint8)ba.size()] = crc16&0xFF;
    emit toUishowMsgPack(sendModbusmsg);
    emit analysis_over(sendModbusmsg);
    sendModbusmsg.clear();
}


//03功能码解析
void analysis::analysis03()
{
    quint16 num =((quint8)recvModbusmsg[4])*256+(quint8)recvModbusmsg[5];
    quint16 startaddr =((quint8)recvModbusmsg[2])*256+(quint8)recvModbusmsg[3];
    //单元标识符
    sendModbusmsg[0]=recvModbusmsg[0];
    //功能码
    sendModbusmsg[1]=recvModbusmsg[1];
    //字节计数
    sendModbusmsg[2]=(quint8)num*2;
    //状态值
    for(quint16 i=3,z=0,j=startaddr;z<num;z++,j++)
    {
        //读出寄存器数据
        QString registerData = readseting->value("Section" + QString::number(j+1) + "/regi").toString();
        sendModbusmsg[i++]=((quint16)registerData.toInt())>>8;
        sendModbusmsg[i++]=((quint16)registerData.toInt())&0xFF;
        msg.push_back((quint16)registerData.toInt());
    }
    ReadRegsPackMsgToShow(startaddr,num,msg);
    msg.clear();
    //CRC校验
    QByteArray crcba(sendModbusmsg,5+num*2);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    sendModbusmsg[3+num*2] = crc16>>8;
    //CRC校验低位
    sendModbusmsg[4+num*2] = crc16&0xFF;
    emit toUishowMsgPack(sendModbusmsg);
    emit analysis_over(sendModbusmsg);
    sendModbusmsg.clear();
}
//0f功能码解析
void analysis::analysis0f()
{
    QByteArray ba;
    quint16 startaddr =((quint8)recvModbusmsg[2])*256+(quint8)recvModbusmsg[3];
    quint16 datanum = ((quint8)recvModbusmsg[4])*256+(quint8)recvModbusmsg[5];
    quint16 sizenum = (quint8)recvModbusmsg[6];
    //读取数据
    for(int i=0;i<sizenum;i++)
    {
        ba[i]=recvModbusmsg[7+i];
    }
    //转化为二进制字符串
    HexByteArrayToBinString(ba);
    //更新表格
    emit wirtTablec(datanum,startaddr,HexByteArrayToBinString(ba));
    //写入文件
    WriteData0X0F(startaddr,HexByteArrayToBinString(ba));
    //读出写入数据
    WirteCoilPackMsgToShow(startaddr,datanum,ba);
    //回应报文
    ba = recvModbusmsg.mid(0,6);
    //CRC校验
    QByteArray crcba(ba,8);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    ba[6] = crc16>>8;
    //CRC校验低位
    ba[7] = crc16&0xFF;
    emit toUishowMsgPack(ba);
    emit analysis_over(ba);
    bac.clear();
}
//10功能码解析
void analysis::analysis10()
{
    QByteArray ba;
    quint16 startaddr =((quint8)recvModbusmsg[2])*256+(quint8)recvModbusmsg[3];
    quint16 datanum = ((quint8)recvModbusmsg[4])*256+(quint8)recvModbusmsg[5];
    //读取数据
    for(int j=7,z=0,k=startaddr;z<datanum;k++,z++)
    {
        quint16 coildata=((quint8)recvModbusmsg[j++])*256+(quint8)recvModbusmsg[j++];
        bar.push_back(coildata);
        //写入文件
        QString s = "Section" + QString::number(k+1) + "/regi";
        readseting->setValue(s,coildata);
    }
    //更新表格
    emit wirtTabler(datanum,startaddr,bar);
    WirteRegsPackMsgToShow(startaddr,datanum,bar);
    //回应报文
    ba = recvModbusmsg.mid(0,6);
    //CRC校验
    QByteArray crcba(ba,8);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    ba[6] = crc16>>8;
    //CRC校验低位
    ba[7] = crc16&0xFF;
    emit toUishowMsgPack(ba);
    emit analysis_over(ba);
    sendModbusmsg.clear();
    bar.clear();
}

//异常码01处理
void analysis::abnormal_01()
{
    QByteArray ba;
    ba = recvModbusmsg.mid(0,2);
    ba[1]=mb_code+0x80;
    ba[2]=0x01;
    //CRC校验
    QByteArray crcba(ba,5);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    ba[3] = crc16>>8;
    //CRC校验低位
    ba[4] = crc16&0xFF;
    emit toUishowMsgPack(ba);
    emit analysis_over(ba);
}
//02异常码处理
void analysis::abnormal_02()
{
    QByteArray ba;
    //回应报文
    ba = recvModbusmsg.mid(0,2);
    ba[1] = (mb_code+0x80);
    ba[2] = 0x02;
    //CRC校验
    QByteArray crcba(ba,5);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    ba[3] = crc16>>8;
    //CRC校验低位
    ba[4] = crc16&0xFF;
    emit toUishowMsgPack(ba);
    emit analysis_over(ba);
}
//03异常码处理
void analysis::abnormal_03()
{
    QByteArray ba;
    //回应报文
    ba = recvModbusmsg.mid(0,2);
    ba[1] = (mb_code+0x80);
    ba[2] = 0x03;
    //CRC校验
    QByteArray crcba(ba,5);
    quint16 crc16 = crc16ForModbus(crcba,CRC_FLAG);
    //CRC校验高位
    ba[3] = crc16>>8;
    //CRC校验低位
    ba[4] = crc16&0xFF;
    emit toUishowMsgPack(ba);
    emit analysis_over(ba);
}

//  响应报文
void analysis::GetData0X01(QByteArray &coilsDataArr, quint16 BeginAddress, quint16 Number)
{
    //声明读取的数据字符串
    QString getDataString;
    quint8 responseMessageByteNum;
    //求响应报文字节数
    responseMessageByteNum = (quint8)((Number + 7) / 8);

    //从数据表中读取需要数量的线圈数据,形成二进制形式字符串
    for(quint32 i = BeginAddress; i < (BeginAddress + Number); i++)
    {
        //读出线圈数据
        QString buffer = readseting->value("Section" + QString::number(i+1) + "/coil").toString();
        if(buffer == "1")
        {
            getDataString += "1";
        }
        else
        {
            getDataString += "0";
        }
    }
    //二进制字符串补0
    for(int i = 1; i <= (8*responseMessageByteNum - Number); i++)
    {
        getDataString += "0";
    }
    //coilsDataArr.resize(responseMessageByteNum);
    //将二进制字符串按字节填入响应报文数组
    for(int i = 0; i < responseMessageByteNum; i++)
    {
        //对8位1字节进行反转处理
        QString buffer = getDataString.mid((8 * i),8);
        //字节反转
        byteReverse(buffer);
        //存入响应报文数组
        coilsDataArr[i] = buffer.toInt(NULL,2);
    }
}
//写入多个线圈
void analysis::WriteData0X0F(quint16 satrt, QString CoilData)
{
    //更新ini文件数据
    for(int j=0,k=satrt;j<CoilData.length();j++,k++)
    {
        QString s = "Section" + QString::number(k+1) + "/coil";
        quint8 coildata;
        if(CoilData.at(j)=='1')
        {
            coildata = 1;
        }
        else
        {
            coildata = 0;
        }
        readseting->setValue(s,coildata);
    }
}

//读出线圈并显示
void analysis::ReadCoilPackMsgToShow(quint16 startaddr,quint16 num,QByteArray msg)
{
    quint8 size = msg.size();
    QString msgs;
    for(quint8 i=0;i<size;i++)
    {
        //先转化为2进制字符串
        QString str = QString::number((quint8)msg.at(i),2);
        //再转化为2进制整形，由二进制整形转化为8位2进制字符串前面自动补0，从而保证8位
        str = QString("%1").arg((quint8)str.toInt(NULL,2),8,2,QChar('0'));
        //8bit字节倒转
        //byteReverse(str);
        //添加到数据中
        msgs += str;

    }
    //去除填充的0位，读出请求报文请求的线圈数
    msgs = msgs.right(num);
     emit toUishowMsg("成功读出线圈");
     emit toUishowMsg(QString("起始地址:%1").arg(startaddr)+"             "+QString("数量:%1\r\n").arg(num));
     emit toUishowMsg(msgs+"\n");
}
//处理报文 读出寄存器
void analysis::ReadRegsPackMsgToShow(quint16 startaddr, quint16 num, QVector<quint16> msg)
{
    quint8 size = msg.size();
    QString msgs;
    quint16 data;
    for(quint8 i=0;i<size;i++)
    {
        QString str;
        data= msg.at(i);
        str = QString("%1 ").arg(data);
        msgs+=str;
    }
    emit toUishowMsg("成功读出寄存器的数据\n");
    emit toUishowMsg(QString("起始地址:%1").arg(startaddr)+"             "+QString("数量:%1\r\n").arg(num));
    emit toUishowMsg(msgs+"\n");
    qDebug()<<(msgs);
    msgs.clear();
    msg.clear();
}


void analysis::Reverse(char str[]){
    int n=strlen(str);
    int i;
    char temp;
    for(i=0;i<(n/2);i++){
        temp=str[i];
        str[i]=str[n-i-1];
        str[n-i-1]=temp;
    }
}

//报文线圈数据写入提示
void analysis::WirteCoilPackMsgToShow(quint16 startaddr, quint16 num, QByteArray msg)
{
    quint8 size = msg.size();
    QString msgs;
    for(quint8 i=0;i<size;i++)
    {
        //先转化为2进制字符串
        QString str = QString::number((quint8)msg.at(i),2);
        //再转化为2进制整形，由二进制整形转化为8位2进制字符串前面自动补0，从而保证8位
        str = QString("%1").arg((quint8)str.toInt(NULL,2),8,2,QChar('0'));
        //8bit字节倒转
       byteReverse(str);
        //添加到数据中
        msgs += str;
    }
    //去除填充的0位，读出请求报文请求的线圈数
    msgs = msgs.left(num);
    emit toUishowMsg("已写入线圈的数据\n");
    emit toUishowMsg(QString("起始地址:%1").arg(startaddr)+"             "+QString("数量:%1\r\n").arg(num));
    emit toUishowMsg(msgs+"\n");
//    QByteArray str = msgs.toLatin1();
//    char* ch;
//    ch = str.data();
//    Reverse(ch);
//    QString str1 = QString::fromUtf8(ch);
//    emit toUishowMsg(str1+"\n");
    msgs.clear();
}
//写入寄存器并提示信息
void analysis::WirteRegsPackMsgToShow(quint16 startaddr, quint16 num, QVector<quint16> msg)
{
    quint8 size = msg.size();
    QString msgs;
    quint16 data;
    for(quint8 i=0;i<size;i++)
    {
        QString str;
        data= (quint16)msg.at(i);
        str = QString("%1 ").arg(data);
        msgs+=str;
    }
    emit toUishowMsg("成功写入寄存器的数据\n");
    emit toUishowMsg(QString("起始地址:%1").arg(startaddr)+"             "+QString("数量:%1\r\n").arg(num));
    emit toUishowMsg(msgs+"\n");
    msgs.clear();
}

//16进制转2进制
QString analysis::HexByteArrayToBinString(QByteArray DataArray)
{
    //2进制字符串的长度
    quint16 DataArrayLength;
    DataArrayLength = DataArray.size();
    QString res;
    for(int i = 0; i < DataArrayLength; i++)
    {
        //先转化为2进制字符串
        QString str = QString::number((quint8)DataArray.at(i),2);
        //再转化为2进制整形，由二进制整形转化为8位2进制字符串前面自动补0，从而保证8位
        str = QString("%1").arg((quint8)str.toInt(NULL,2),8,2,QChar('0'));
        //8bit字节倒转
        byteReverse(str);
        res += str;
    }
    return res;
}









